home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / CODECS.ZIP / codecs / francais / codrle2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-13  |  7.1 KB  |  184 lines

  1. /* Fichier: codrle2.c
  2.    Auteur: David Bourgin
  3.    Date de creation: 1/2/94
  4.    Date de derniere mise a jour: 24/7/95
  5.    Dessein: Exemple de codage RLE type 2 avec comme donnees a compresser le contenu d'un fichier.
  6. */
  7.  
  8. #include <stdio.h>
  9. /* Pour les routines printf,fgetc,fputc et rewind */
  10. #include <memory.h>
  11. /* Pour la routine memset */
  12. #include <stdlib.h>
  13. /* Pour la routine exit */
  14.  
  15. /* Codes d'erreur renvoyes a l'appelant */
  16. #define NO_ERROR      0
  17. #define BAD_FILE_NAME 1
  18. #define BAD_ARGUMENT  2
  19.  
  20. /* Constantes pratiques */
  21. #define FALSE 0
  22. #define TRUE  1
  23.  
  24. /* Variables globales */
  25. FILE *f_source,*f_dest;
  26.  
  27.                              /* Puisque fgetc=EOF uniquement apres un acces
  28.                                 alors statut_octet_stocke vaut TRUE si un octet a ete engrange par fgetc
  29.                                 ou FALSE s'il n'y aucun octet valide, deja lu et non traite dans val_octet_stocke */
  30. int statut_octet_stocke=FALSE;
  31. int val_octet_stocke;
  32.  
  33. /* Pseudo procedures */
  34. #define debut_des_donnees()  (statut_octet_stocke=FALSE,(void)rewind(f_source))
  35. #define fin_des_donnees() (statut_octet_stocke?FALSE:!(statut_octet_stocke=((val_octet_stocke=fgetc(f_source))!=EOF)))
  36. #define lire_octet()  (statut_octet_stocke?statut_octet_stocke=FALSE,(unsigned char)val_octet_stocke:(unsigned char)fgetc(f_source))
  37. #define ecrire_octet(octet)  ((void)fputc((octet),f_dest))
  38.  
  39. void ecrire_reprle2(octet_repere,octet_repete,nombre_repetition)
  40. /* Parametres en sortie: Aucun
  41.    Action: Ecrit dans le flux de sortie de compression le codage de nombre_repetition fois l'octet_repete.
  42.    octet_repere fait office de marqueur comme defini par la methode RLE 2
  43.    Erreurs: Une erreur d'entree/sortie peut perturber le deroulement de l'algorithme
  44. */
  45. unsigned char octet_repere,octet_repete;
  46. unsigned int nombre_repetition;
  47. { if (nombre_repetition<4)
  48.      if (octet_repete==octet_repere)
  49.         { ecrire_octet(octet_repere);
  50.           ecrire_octet(nombre_repetition-1);
  51.         }
  52.      else { register unsigned int i;
  53.  
  54.             for (i=1;i<=nombre_repetition;i++)
  55.                 ecrire_octet(octet_repete);
  56.           }
  57.   else { ecrire_octet(octet_repere);
  58.          ecrire_octet(nombre_repetition-1);
  59.          ecrire_octet(octet_repete);
  60.        }
  61. }
  62.  
  63. void ecrire_non_reprle2(octet_repere,octet_non_repete)
  64. /* Parametres en sortie: Aucun
  65.    Action: Ecrit dans le flux de sortie de compression l'octet_non_repete
  66.    octet_repere fait office de marqueur comme defini par la methode RLE 2
  67.    Erreurs: Une erreur d'entree/sortie peut perturber le deroulement de l'algorithme
  68. */
  69. unsigned char octet_repere,octet_non_repete;
  70. { if (octet_non_repete==octet_repere)
  71.      { ecrire_octet(octet_repere);
  72.        ecrire_octet(0);
  73.      }
  74.   else ecrire_octet(octet_non_repete);
  75. }
  76.  
  77. void codagerle2()
  78. /* Parametres en sortie: Aucun
  79.    Action: Compresse suivant la methode RLE type 2 tous les octets lus par la fonction lire_octet
  80.    Erreurs: Une erreur d'entree/sortie peut perturber le deroulement de l'algorithme
  81. */
  82. { unsigned char octet1,octet2,octet_repere;
  83.   unsigned int taille_trame;
  84.   register unsigned int i;
  85.   unsigned long int table_occurrences[256];
  86.  
  87.   if (!fin_des_donnees())    /* Y a-t-il au moins 1 octet a analyser? */
  88.      {                       /* Initialiser le nombre d'occurrences de tous les octets a 0 */
  89.        (void)memset((char *)table_occurrences,0,sizeof(table_occurrences));
  90.                              /* Ceci equivaut a remplir table_occurrences de 0.
  91.                                 C'est plus rapide que boucler 256 fois */
  92.                         /* Valider les occurrences de table_occurrences en fonction des donnees a compresser */
  93.        while (!fin_des_donnees())
  94.              { octet1=lire_octet();
  95.                table_occurrences[octet1]++;
  96.              }
  97.        octet_repere=0;
  98.        for (i=1;i<=255;i++)
  99.            if (table_occurrences[i]<table_occurrences[octet_repere])
  100.               octet_repere=i;
  101.        ecrire_octet(octet_repere);
  102.        debut_des_donnees();  /* Nouvelle analyse des donnees */
  103.        octet1=lire_octet();
  104.        taille_trame=1;
  105.        if (!fin_des_donnees())
  106.                              /* Y a-t-il au moins 2 octets a analyser? */
  107.           { octet2=lire_octet();
  108.             taille_trame=2;
  109.             do {             /* Debut de compression a proprement parle */
  110.                  if (octet1==octet2)
  111.                              /* N'a-t-on rencontre qu'une sequence d'octets identiques? */
  112.                     { while ((!fin_des_donnees())&&(octet1==octet2)&&(taille_trame<256))
  113.                             { octet2=lire_octet();
  114.                               taille_trame++;
  115.                             }
  116.                       if (octet1==octet2)
  117.                          { ecrire_reprle2(octet_repere,octet1,taille_trame);
  118.                            if (!fin_des_donnees())
  119.                               { octet1=lire_octet();
  120.                                 taille_trame=1;
  121.                               }
  122.                            else taille_trame=0;
  123.                          }
  124.                       else { ecrire_reprle2(octet_repere,octet1,taille_trame-1);
  125.                              octet1=octet2;
  126.                              taille_trame=1;
  127.                            }
  128.                     }
  129.                  else {      /* Non, alors ne pas prendre en compte le dernier octet */
  130.                         ecrire_non_reprle2(octet_repere,octet1);
  131.                         octet1=octet2;
  132.                         taille_trame=1;
  133.                       }
  134.                  if (!fin_des_donnees())
  135.                     { octet2=lire_octet();
  136.                       taille_trame=2;
  137.                     }
  138.                }
  139.             while ((!fin_des_donnees())||(taille_trame>=2));
  140.           }
  141.        if (taille_trame==1)  /* Il restait un dernier octet a analyser */
  142.           ecrire_non_reprle2(octet_repere,octet1);
  143.      }
  144. }
  145.  
  146. void aide()
  147. /* Parametres en sortie: Aucun
  148.    Action: Affiche l'aide du programme et termine son execution
  149.    Erreurs: Aucune
  150. */
  151. { printf("Cet utilitaire permet de compresser un fichier par la methode RLE type 2\n");
  152.   printf("telle qu'elle est exposee dans 'La Video et Les Imprimantes sur PC'\n");
  153.   printf("\nUsage: codrle2 source destination\n");
  154.   printf("source: Nom du fichier a compresser\n");
  155.   printf("destination: Nom du fichier compresse\n");
  156. }
  157.  
  158. int main(argc,argv)
  159. /* Parametres en sortie: Renvoie un code d'erreur (0=Aucune)
  160.    Action: Procedure principale
  161.    Erreurs: Detectee, traitee et un code d'erreur est renvoye si necessaire
  162. */
  163. int argc;
  164. char *argv[];
  165. { if (argc!=3)
  166.      { aide();
  167.        exit(BAD_ARGUMENT);
  168.      }
  169.   else if ((f_source=fopen(argv[1],"rb"))==NULL)
  170.           { aide();
  171.             exit(BAD_FILE_NAME);
  172.           }
  173.        else if ((f_dest=fopen(argv[2],"wb"))==NULL)
  174.                { aide();
  175.                  exit(BAD_FILE_NAME);
  176.                }
  177.             else { codagerle2();
  178.                    fclose(f_source);
  179.                    fclose(f_dest);
  180.                  }
  181.   printf("Execution de codrle2 achevee.\n");
  182.   return (NO_ERROR);
  183. }
  184.